/*
*uploading.c
*/

#include "uploading.hh"
using namespace std;

void* Uploader::thread_handler(void* param){
  param_uploader* temp=(param_uploader*)param;
  Uploader *obj=temp->obj;
  int count=0;
  int filesize=0;
  free(temp);
   Item_t output;
   obj->ringBuffer_->Extract(&output);

     if(output.type==FILE_HEAD){
    	 memcpy(obj->uploaderMetaBuffer_+obj->metaWP_,&(output.fileObj),obj->fileMDHeadsize_);
    	 obj->metaWP_+=obj->fileMDHeadsize_;
    	filesize=output.fileObj.filesize;
       printf("the uploading: the file size is %d\n",filesize);
     }

     obj->uploaderContainer_=(char*)malloc(sizeof(char)*filesize);

  while(true) {
  
    obj->ringBuffer_->Extract(&output);

    if(output.type==BLOCKCP ||output.type==BLOCKCP_END){
    /* see if the container buffer can hold the coming share, if not then perform upload */
      int blocksize=output.blockcpObj.blockcp_header.blockcpSize;
       //if(blocksize+obj->containerWP_>UPLOAD_BUFFER_SIZE)  {
      //  obj->performUpload();
     //  }

     //copy blockcp header into metabuffer
      memcpy(obj->uploaderMetaBuffer_+obj->metaWP_,&(output.blockcpObj.blockcp_header),obj->blockcpMDHeadsize_);
      obj->metaWP_+=obj->blockcpMDHeadsize_;
      /* copy share data into container buffer */
      memcpy(obj->uploaderContainer_+obj->containerWP_,output.blockcpObj.data,blocksize);
      obj->containerWP_+=blocksize;

      //printf("uploading::==============the cipertext is %s\n",obj->uploaderContainer_);
      printf("uploading--------------,%d,%d\n",output.type,output.blockcpObj.blockcp_header.blockcpid);
     }
     else if(output.type==FILE_HF)
        {
            printf("-----%d,%d\n",obj->containerWP_,filesize);   
                 obj->performUpload(output.hfObj.hf,obj->uploaderContainer_);
                // printf("uploading:total cipertext:%s\n",obj->uploaderContainer_);
            pthread_exit(NULL);
         }
  }
   free(obj->uploaderContainer_);
   if(obj->uploaderContainer_!=NULL)
    printf("obj->uploaderContainer_ has not free\n");
}


Uploader::Uploader(int total,int subset,int userID){

  uploaderMetaBuffer_=(char*)malloc(sizeof(char)* UPLOAD_BUFFER_SIZE);
  ringBuffer_=new RingBuffer<Item_t>(UPLOAD_RB_SIZE,true,1);
  metaWP_=0;
  containerWP_=0;
  blockcpMDHeadsize_=sizeof(blockCpMDHead_t);
  fileMDHeadsize_=sizeof(fileMDHead_t);
  FILE* fin=fopen("./config","rb");
  param_uploader* param=(param_uploader*)malloc(sizeof(param_uploader));
  param->index=0;
  param->obj=this;

  pthread_create(&tid_,0,&thread_handler,(void*)param);
  char line[255];
  char ch[2]=":";
  int res=fscanf(fin,"%s",line);
  if(res==0)
  printf("read line failure!\n");
  char *token=strtok(line,ch);
  char *ip=token;
  token=strtok(NULL,ch);
  int port=atoi(token);
  socket_=new Socket(ip,port,userID);
  fclose(fin);
 }
Uploader::~Uploader(){
free(uploaderMetaBuffer_);
delete(ringBuffer_);
delete(socket_);
}


void Uploader::indicateEnd(){
    pthread_join(tid_,NULL);
}


int Uploader::add(Item_t item, int size){
 ringBuffer_->Insert(&item,size);
 printf("uploadding:: it has added one ciperblock\n");
return 1;
}

int Uploader::performUpload(char* hf,char* buffer){
 //printf("uploading:total cipertext:%s\n",buffer);
 int i;
  if(socket_->sendHfMeta(hf,32)==32){
   printf("the hf has send\n");
 }
 if(socket_->getStatuForfile(&i)==0) {
    if(i==FILE_NOT_EXIST){
    	if(socket_->sendMeta(uploaderMetaBuffer_,metaWP_)==metaWP_){
         printf("it has upload  meta data into cloud!  %d\n",metaWP_);
        }
    	if(socket_->sendData(buffer,containerWP_)==containerWP_){     
    		printf("it has upload data into cloud! %d\n",containerWP_);
           return 0;
        }
    }else {
     printf("the file has storaged\n");
     return -1;
     }
 }
 }






